{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <div align='center'>初探:感知机</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import matplotlib.pylab as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['font.sans-serif'] = 'SimHei'\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "plt.rcParams['figure.figsize'] = (16.0, 8.0)\n",
    "plt.rcParams[\"axes.grid\"] = True\n",
    "plt.rcParams[\"grid.linestyle\"] = (5,9)\n",
    "plt.rcParams['text.usetex'] = True\n",
    "plt.rcParams['text.latex.preamble'] = [r'\\usepackage{amsmath}']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "感知机灵感"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "#####################################################################################\n",
    "# <codecell>\n",
    "#####################################################################################\n",
    "#                      ╱\n",
    "#                    ╲╱\n",
    "#                     ╲ ╱                                神经末梢\n",
    "#          │           ╳                             ╲ /\n",
    "#         ─┘╲         ╱                               ╳\n",
    "#      ╳  ╱  ╲       ╱                                 ╲\n",
    "#     ╱ ╲╱    ╲     ╱                                   ╳\n",
    "#       ╱        *******                               ╱     ╳\n",
    "#             ***       ***  轴突:转出信号到其他神经元╱     ╱ ╲\n",
    "#             *   细胞核  * ══════════════════════════╲  ╳ ╱\n",
    "#          ╳  ***       ***                            ╲╱ ╳\n",
    "#         ╱ ╲  ╱ *******                                ╲     ╱\n",
    "#     ╲  ╱   ╲╱                                          ╲   ╳\n",
    "#      ╲╱    ╱                                            ╲ ╱ ╲\n",
    "#      ╱    ╳                                              ╳   ╲\n",
    "#          ╱ ╲\n",
    "#             ╲ 树突: 接收信号\n",
    "#                                            生物神经元\n",
    "#\n",
    "#######################################################################################\n",
    "#\n",
    "#\n",
    "#                                    单层感知机\n",
    "#                     x1  ╲\n",
    "#                          ╲\n",
    "#                           ╲\n",
    "#                         w1 ╲       *********\n",
    "#                             ╲    **         **\n",
    "#                              v **             **\n",
    "#                      w2       *                 *   f(z) = sign(z)\n",
    "#               x2 ──────────> *  sum(w_i*x_i +b) *  ────────────────> y\n",
    "#           树突                *                 *   轴突, 激活函数\n",
    "#                              ^ **     z       **\n",
    "#                             ╱    **         **\n",
    "#                         w3 ╱       *********   b: 细胞本身自带的信号, bias偏置值\n",
    "#                           ╱                    w: 输入信号有选择的接收\n",
    "#                          ╱                        如果所有w=1, 输入信号全部进入\n",
    "#                     x3  ╱                         如果所有w=0, 输入信号全部屏蔽\n",
    "#                                                   如果w=?, 对信号有不同程度的作用\n",
    "#\n",
    "#######################################################################################\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0: [[-5]\n",
      " [ 0]\n",
      " [ 1]]\n",
      "1: [[-3]\n",
      " [ 0]\n",
      " [-1]]\n",
      "2: [[-1]\n",
      " [ 0]\n",
      " [-3]]\n",
      "finished\n"
     ]
    }
   ],
   "source": [
    "#####################################################################################\n",
    "# <codecell> 单样本量\n",
    "#####################################################################################\n",
    "\n",
    "X = np.array([[1, 0, -1]]) # shape: (1, 3)\n",
    "W = np.array([[-5], [0], [1]])  # shape: (3, 1)\n",
    "\n",
    "# W最后一个值是bias(偏置)\n",
    "\n",
    "lr = 1 # 学习率\n",
    "target = 1 # 真实值\n",
    "\n",
    "for i in range(150):\n",
    "    print('%d:' % i, W)\n",
    "    y = np.sign(np.dot(X, W)) # 激活函数\n",
    "    if y != target:\n",
    "        # 更新W值\n",
    "        W = W + lr * (target - y) * X.T\n",
    "    else:\n",
    "        print('finished')\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 1. 1. 1. 1. 1.]\n"
     ]
    }
   ],
   "source": [
    "#####################################################################################\n",
    "# <codecell> 多个样本量\n",
    "#####################################################################################\n",
    "\n",
    "X = np.array([\n",
    "    [1, 1, 1],\n",
    "    [1, 1, 3],\n",
    "    [1, 2, 1],\n",
    "    [1, 2, 4],\n",
    "    [1, 3, 2],\n",
    "    [1, 1.5, 5]])\n",
    "\n",
    "print(X[:, 0]) # this is bias\n",
    "\n",
    "W = np.array([[3], [0], [1]]) # start values, the first elem is bias\n",
    "\n",
    "Y = np.array([[1], [1], [1], [-1], [-1], [-1]])\n",
    "\n",
    "def calculate_params(X, Y, W):\n",
    "    m = len(X)\n",
    "    lr = 0.05\n",
    "\n",
    "    for i in range(1000):\n",
    "        if i % 10 == 0:\n",
    "            print('%d\\n' % i, W)\n",
    "        y = np.sign(np.dot(X, W))\n",
    "        if (y != Y).any(): # 如果模型计算的y和已知标签Y的值不一致,更新参数\n",
    "            W = W - lr * np.matmul(X.T, (y-Y)) / m # 矩阵计算, m是样本量\n",
    "        else:\n",
    "            print('finished')\n",
    "            break\n",
    "\n",
    "    # 模拟数据, 在平面中显示这条切线\n",
    "    xs = np.random.uniform(0, 4, 100)\n",
    "    ys = (-W[0] - xs*W[1]) / W[2]\n",
    "    return xs, ys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      " [[3]\n",
      " [0]\n",
      " [1]]\n",
      "finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x7f52076155c0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#####################################################################################\n",
    "# <codecell> plot\n",
    "#####################################################################################\n",
    "\n",
    "xs, ys = calculate_params(X, Y, W)\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(12,6))\n",
    "ax.plot(xs, ys)\n",
    "\n",
    "# xs = X[:, 1]\n",
    "# ys = X[:, 2]\n",
    "\n",
    "xs1 = []\n",
    "ys1 = []\n",
    "\n",
    "xs2 = []\n",
    "ys2 = []\n",
    "\n",
    "for i, v in enumerate(Y.reshape((len(Y), ))):\n",
    "    if v > 0:\n",
    "        xs1.append(X[i][1])\n",
    "        ys1.append(X[i][2])\n",
    "    else:\n",
    "        xs2.append(X[i][1])\n",
    "        ys2.append(X[i][2])\n",
    "\n",
    "\n",
    "ax.scatter(xs1, ys1, s=100, lw=2, marker='+')\n",
    "ax.scatter(xs2, ys2, s=100, lw=2, marker='o')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      " [[3]\n",
      " [0]\n",
      " [1]]\n",
      "10\n",
      " [[ 2.64285714]\n",
      " [-0.75714286]\n",
      " [-0.36      ]]\n",
      "finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x7f52075585c0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#####################################################################################\n",
    "# <codecell> add one point\n",
    "#####################################################################################\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(12,6))\n",
    "\n",
    "ax.plot(xs, ys)\n",
    "ax.scatter(xs1, ys1, s=100, lw=2, marker='+')\n",
    "ax.scatter(xs2, ys2, s=100, lw=2, marker='o')\n",
    "\n",
    "# 添加一个样本\n",
    "X = np.vstack((X, [[1, 2.5, 1.8]]))\n",
    "Y = np.vstack((Y, [[1]]))\n",
    "\n",
    "xs, ys = calculate_params(X, Y, W)\n",
    "ax.plot(xs, ys, color='red')\n",
    "ax.scatter(X[-1][1], X[-1][2], s=60, lw=2, marker='^', color='blue')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
